package edu.lsnu.equipment_management_system.service.impl;

import edu.lsnu.equipment_management_system.mapper.select.nopaging.CheckBoxMapper;
import edu.lsnu.equipment_management_system.pojo.po.EquipmentThreeLevelLinkagePo;
import edu.lsnu.equipment_management_system.pojo.po.UserTwoLevelLinkagePo;
import edu.lsnu.equipment_management_system.pojo.vo.out.linkage.equipment.EquipmentCategoryVo;
import edu.lsnu.equipment_management_system.pojo.vo.out.linkage.equipment.EquipmentNameVo;
import edu.lsnu.equipment_management_system.pojo.vo.out.linkage.user.UserLinkageVo;
import edu.lsnu.equipment_management_system.service.CheckBoxService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author mzy
 * @Description
 * @date 2018/11/16
 */
@Service
public class CheckBoxServiceImpl implements CheckBoxService {
    @Autowired
    CheckBoxMapper checkBoxMapper;

    /**
     * @Description 用户在用中设备三级联动
     * @author mzy
     * @time 2018-11-23
     * @see
     * @return   java.util.LinkedList<edu.lsnu.equipment_management_system.pojo.vo.out.linkage.equipment.EquipmentCategoryVo>
     * @params  [userId]
     */
    @Override
    public LinkedList<EquipmentCategoryVo> getUserEquipmentThreeLevelLinkageVo(String userNo) {
        List<EquipmentThreeLevelLinkagePo> threeLevelLinkagePoList =
                checkBoxMapper.getUserEquipmentThreeLevelLinkagePo(userNo);

        LinkedList<EquipmentCategoryVo> categoryVos =
                getEquipmentThreeLevelLinkage(threeLevelLinkagePoList);

        return  categoryVos;
    }

    /**
     * @Description 管理员所有设备三级联动
     * @author mzy
     * @time 2018-11-23
     * @see
     * @return   java.util.LinkedList<edu.lsnu.equipment_management_system.pojo.vo.out.linkage.equipment.EquipmentCategoryVo>
     * @params  []
     */
    @Override
    public LinkedList<EquipmentCategoryVo> getAdminEquipmentThreeLevelLinkageVo() {
        List<EquipmentThreeLevelLinkagePo> threeLevelLinkagePoList =
                checkBoxMapper.getAdminEquipmentThreeLevelLinkagePo();

        LinkedList<EquipmentCategoryVo> categoryVos =
                getEquipmentThreeLevelLinkage(threeLevelLinkagePoList);

        return  categoryVos;
    }

    /**
     * @Description 用户职工号姓名二级联动
     * @author mzy
     * @time 2018-11-23
     * @see
     * @return   java.util.LinkedList<edu.lsnu.equipment_management_system.pojo.vo.out.linkage.user.UserLinkageVo>
     * @params  []
     */
    @Override
    public LinkedList<UserLinkageVo> getUserTwoLevelLinkageVo() {
        List<UserTwoLevelLinkagePo> userTwoLevelLinkagePoList =
                checkBoxMapper.getUserTwoLevelLinkagePo();

        LinkedList<UserLinkageVo> userTwoLevelLinkage =
                getUserTwoLevelLinkage(userTwoLevelLinkagePoList);
        return userTwoLevelLinkage;
    }

    /**
     * @Description 把po中的设备的三级联动转化成vo中的三级联动
     * @author mzy
     * @time 2018-11-18
     * @see
     * @return   java.util.LinkedList<edu.lsnu.equipment_management_system.pojo.vo.out.linkage.equipment.EquipmentCategoryVo>
     * @params  [threeLevelLinkagePoList]
     */
    private LinkedList<EquipmentCategoryVo>
    getEquipmentThreeLevelLinkage
    (List<EquipmentThreeLevelLinkagePo> threeLevelLinkagePoList) {

        Map<String, Map<String, Set<String>>> threeLevelLinkageMap = new TreeMap<>();

        // 将所有的equipmentCategory放到第一级
        Map<String, Set<String>> categoryContent;
        for (EquipmentThreeLevelLinkagePo po : threeLevelLinkagePoList) {
            categoryContent = new TreeMap<>();
            threeLevelLinkageMap.put(po.getEquipmentCategory(), categoryContent);
        }

        // 将所有的equipmentName放到第二级
        TreeSet<String> nameContent;
        for (EquipmentThreeLevelLinkagePo po : threeLevelLinkagePoList) {
            nameContent = new TreeSet<>();
            threeLevelLinkageMap.get(po.getEquipmentCategory()).put(po.getEquipmentName(), nameContent);
        }

        // 将所有的equipmentNo放到第三级
        for (EquipmentThreeLevelLinkagePo po : threeLevelLinkagePoList) {
            threeLevelLinkageMap.get(po.getEquipmentCategory()).get(po.getEquipmentName())
                    .add(po.getEquipmentNo());
        }

        // System.out.println(threeLevelLinkageMap);

        // 从map拷贝到界面需要的List中去
        // ---------------------------------
        // 装最外层类别的List
        LinkedList<EquipmentCategoryVo> categoryVos = new LinkedList<>();

        // 遍历出一个个的EquipmentCategoryVo，并尝试放入到categoryVos中
        EquipmentCategoryVo equipmentCategoryVo;
        LinkedList<EquipmentNameVo> nameVos;
        // 得到EquipmentCategory对应的最外层的Map的Entry
        // Map<key：EquipmentCategory +  value：Map<key：EquipmentName + value：Set<EquipmentNo> > >
        // -------- >>>
        // Map.Entry<key：EquipmentCategory +  value：Map<key：EquipmentName + value：Set<EquipmentNo> > >
        for (Map.Entry<String, Map<String, Set<String>>> categoryEntry : threeLevelLinkageMap.entrySet()) {
            // 实例化当前轮需要的EquipmentCategoryVo对象
            equipmentCategoryVo = new EquipmentCategoryVo();
            // 实例化当前轮EquipmentCategoryVo下需要的EquipmentNameVo的List
            nameVos = new LinkedList<>();

            // 得到当前轮EquipmentCategory的Entry的value
            // value包括：(Map【key：EquipmentName + value：Set EquipmentNo】)
            Map<String, Set<String>> nameMap = categoryEntry.getValue();

            // 遍历出一个个的EquipmentNameVo，并尝试放入到nameVos中
            EquipmentNameVo equipmentNameVo;
            LinkedList<String> noList;
            // 得到EquipmentName对应的Map的内层Entry，以及需封装List的EquipmentNo内容
            // Map<key：EquipmentName + value：Set<EquipmentNo>>
            // -------- >>>
            // Map.Entry<key：EquipmentName + value：Set<EquipmentNo>>
            for (Map.Entry<String, Set<String>> nameEntry: nameMap.entrySet()) {
                equipmentNameVo = new EquipmentNameVo();
                noList = new LinkedList<>();

                // 遍历出编号EquipmentNo
                // Set<EquipmentNo>
                // -------- >>>
                // Map.Entry<EquipmentNo>
                for (String no : nameEntry.getValue()) {
                    noList.add(no);
                }
                // 每一轮重新创建的equipmentNameVo，
                // 把key(equipmentName)和list(List<EquipmentNo>)，分别set进去
                equipmentNameVo.setEquipmentName(nameEntry.getKey());
                equipmentNameVo.setEquipmentNo(noList);
                // 添加到上层的EquipmentNameVo的List(nameVos)中去
                nameVos.add(equipmentNameVo);
            }
            // 每一轮重新创建的equipmentCategoryVo，
            // 把key(equipmentCategory)和list(List<EquipmentName>)，分别set进去
            equipmentCategoryVo.setEquipmentCategory(categoryEntry.getKey());
            equipmentCategoryVo.setEquipments(nameVos);

            // 然后把这一轮遍历结束添加的EquipmentCategory
            // 添加到外层创建的List(List<EquipmentCategory>)中去
            categoryVos.add(equipmentCategoryVo);
        }

        return  categoryVos;
    }

    /**
     * @Description 把po中用户的二级联动转化成vo中的二级联动
     * @author mzy
     * @time 2018-11-18
     * @see
     * @return   java.util.LinkedList<edu.lsnu.equipment_management_system.pojo.vo.out.linkage.user_resource.UserLinkageVo>
     * @params  []
     */
    private LinkedList<UserLinkageVo>
    getUserTwoLevelLinkage(List<UserTwoLevelLinkagePo> userTwoLevelLinkagePoList) {

        // 1.开始把数据塞进Map
        Map<String, Set<String>> twoLinkageMap = new TreeMap<>();
        Set<String> userNoSet;
        // 先将所有的key(userName)添加进去，往value的地方塞一个set
        for (UserTwoLevelLinkagePo po : userTwoLevelLinkagePoList) {
            userNoSet = new TreeSet<>();
            twoLinkageMap.put(po.getUserName(), userNoSet);
        }

        // 开始往set中塞数据
        for (UserTwoLevelLinkagePo po : userTwoLevelLinkagePoList) {
            // map.get(key) [set]
            // set.add(value)
            twoLinkageMap.get(po.getUserName()).add(po.getUserNo());
        }

        // 2.把map中的数据转塞入List
        LinkedList<UserLinkageVo> userList =  new LinkedList<>();

        // 准备好一个UserLinkageVo，用于每轮轮引
        UserLinkageVo userLinkageVo;
        // 准备好一个List，用于放置userNo的。
        List<String> userNoList;
        for (Map.Entry<String, Set<String>> userEntry : twoLinkageMap.entrySet()) {
            // 每轮创建一个UserLinkageVo
            userLinkageVo = new UserLinkageVo();
            // 每轮创建一个存放userNo(userId)的list
            userNoList = new LinkedList<>();

            for (String userNo : userEntry.getValue()) {
                userNoList.add(userNo);
            }
            // 拿到list之后，同时把name和no(List)都set到UserLinkageVo中去
            userLinkageVo.setUserName(userEntry.getKey());
            userLinkageVo.setUserNo(userNoList);

            // 再把userLinkageVo添加到外层的userList中去
            userList.add(userLinkageVo);
        }
        return userList;
    }
}
